package com.vhly.kxmlext.outputer;

import org.kxml2.kdom.Document;
import org.kxml2.kdom.Element;

import java.io.*;

/**
 * Created by IntelliJ IDEA.
 * User: vhly[FR]
 * Date: 2010-4-8
 * Time: 12:55:26
 */
public final class XMLOutputter {

    public static final int TEXT_MODE_NOMAL = 0;
    public static final int TEXT_MODE_TRIM = 1;
    public static final int TEXT_MODE_WHITE_REPLACE = 2;

    public char lineSeparator;
    public boolean expandEmptyElements;
    public int textMode;
    public String encoding;

    public XMLOutputter() {
        this("UTF-8", '\n', 0, false);
    }

    public XMLOutputter(String encoding, char lineSeparator, int textMode, boolean expandEmptyElements) {
        this.encoding = encoding;
        this.lineSeparator = lineSeparator;
        this.textMode = textMode;
        this.expandEmptyElements = expandEmptyElements;
    }

    public void output(Document dom, OutputStream out) {
        if (dom != null && out != null) {
            OutputStreamWriter ow = null;
            BufferedWriter bw = null;
            try {
                ow = new OutputStreamWriter(out, encoding);
                bw = new BufferedWriter(ow);
                output(dom, bw);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bw != null) {
                    try {
                        bw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    bw = null;
                }
                if (ow != null) {
                    try {
                        ow.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    ow = null;
                }
            }
        }
    }

    private void output(Document dom, Writer writer) throws IOException {
        writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        Element el = dom.getRootElement();
        printElement(el, writer);
        writer.flush();
    }

    private void printElement(Element el, Writer writer) throws IOException {
        String n = el.getName();
        int count = el.getAttributeCount();
        int childCount = el.getChildCount();
        writer.write('<');
        writer.write(n);
        if (count > 0) {
            String an, av;
            for (int i = 0; i < count; i++) {
                an = el.getAttributeName(i);
                av = el.getAttributeValue(i);
                writer.write(' ');
                writer.write(an);
                writer.write("=\"");
                writer.write(av);
                writer.write("\"");
            }
        }
        if (childCount > 0) {
            boolean empty = true;
            Object node;
            for (int i = 0; i < childCount; i++) {
                node = el.getChild(i);
                if (node instanceof Element) {
                    empty = false;
                    break;
                } else if (node instanceof String) {
                    String s = (String) node;
                    if (s.trim().length() > 0) {
                        empty = false;
                        break;
                    }
                }
            }
            if (empty) {
                writer.write("/>");
            } else {
                writer.write('>');
                for (int i = 0; i < childCount; i++) {
                    node = el.getChild(i);
                    if (node instanceof Element) {
                        Element e1 = (Element) node;
                        printElement(e1, writer);
                    } else if (node instanceof String) {
                        String s = (String) node;
                        if (s.length() > 0) {
                            writer.write(s);
                        }
                    }
                }
                writer.write("</");
                writer.write(n);
                writer.write('>');
            }
        } else {
            writer.write("/>");
        }
    }
}
